# -*- coding: utf-8 -*-
# File : web.py
# Author: taoyahui
# Date : 2021/7/13
import sys
sys.path.append('..')
from flask import Flask, request
from utils.ansible_util import *
from utils.path_util import *
from utils import mysql_util
from tasks import inventory_discovery, file_distribute, vul_scan
import results
app = Flask(__name__)
from utils.log_util import logger
from fabric import Connection

@app.route("/")
def hello():
    return "hello world"


@app.route("/patch_deploy", methods=['GET', 'POST'])
def patch_deploy():
    body = request.json
    hosts = body['hosts']
    pkg = body['pkg']
    exucute_res = install_single(hosts, pkg)
    res = {'name': pkg, 'result': exucute_res}
    return res


@app.route("/inventory_discovery", methods=['GET', 'POST'])
def my_inventory_discovery():
    inventory_discovery.inventory_discovery()
    return results.success_result


@app.route("/distribute_file", methods=['GET', 'POST'])
def distribute_file():
    body = request.json
    hosts = body['hosts']
    file_name = body['file_name']
    file_dir = body['file_dir']
    os = body['os']
    print(body)
    if os == 'windows':
        copy_res = file_distribute.win_copy_remote_source(file_name, file_dir, hosts)
    else:
        copy_res = file_distribute.linux_copy_source(file_name, file_dir, hosts)
    res = file_distribute.save_result(copy_res, hosts, file_name)

    return res


@app.route("/vul_scan", methods=['GET', 'POST'])
def vul_scan_service():
    body = request.json
    ip = body['ip']
    hostname = body['hostname']
    vul_scan.vul_scan_integrity(ip, hostname)
    return results.success_result

def install_pkg_fabric(host, pkg):
    c = Connection(f"{host['username']}@{host['ip']}", connect_kwargs={'password': host['password']})
    try:
        res = c.run(f'yum install -y {pkg}')
        logger.info(f"install_pkg_fabric run log:  {res.stdout}")
        return {"success":1, "ip": host['ip']}
    except Exception as e:
        logger.error(f"install_pkg_fabric run log: can't install pkg , error is {e}")
        return {"failed": 1, "ip": host['ip'], "msg": str(e)}
    finally:
        c.close()


def fabric_install_res(res_list):
    fail_msg = {}
    fail_msg['counts_success'] = 0
    fail_msg['counts_fail'] = 0
    fail_msg['counts_unreachable'] = 0
    fail_msg['failed'] = {}
    fail_msg['unreachable'] = {}
    for res in res_list:
        if 'success' in res:
            fail_msg['counts_success'] += 1
        if 'failed' in res:
            fail_msg['counts_fail'] += 1
            ip = res['ip'].replace('.','_')
            msg = res['msg']
            fail_msg['failed'][ip] = 'Failed' + msg
    return fail_msg


def install_single(hosts, pkg):
    ret = 0
    counts = 0
    results = {}
    mi = MyInventory()
    mi._dynamic_inventory(hosts)
    # ansible = MyAnsiable(inventory=mi._inventory, connection='smart')

    #使用python fabric时使用res_list记录执行结果
    res_list = []
    for group, m_hosts in hosts.items():
        #使用python fabric远程安装
        for index, host in enumerate(m_hosts['hosts']):
            res = install_pkg_fabric(host, pkg)
            res_list.append(res)

        # 使用ansible run远程安装
        # ansible.run(hosts=group, module='yum', remote_user='root', args='name=%s state=latest' % (pkg))


    # extra_var = {
    #     'host': 'test',
    #     'username': 'root',
    #     'module_name': [pkg]
    # }
    # abs_path = get_root_dir()
    # ansible.playbook(playbooks=[abs_path + '/playbook/patch_deploy.yaml'], var=extra_var)

    #使用ansible时的结果(result)转换
    # stdresult = ansible.get_result()
    # logger.info(f"install_single 获取安装日志: {stdresult}")
    # result = result_prase(stdresult)
    result = {}
    result = fabric_install_res(res_list)
    return result


def result_prase(result):
    """
    结果转换
    :param result:
    :return:
    """
    fail_msg = {}
    success = result.get('success')
    failed = result.get('failed')
    unreachable = result.get('unreachable')
    counts_success = len(success)
    counts_fail = len(failed)
    counts_unreachable = len(unreachable)

    fail_msg['counts_success'] = counts_success
    fail_msg['counts_fail'] = counts_fail
    fail_msg['counts_unreachable'] = counts_unreachable
    fail_msg['failed'] = {}
    fail_msg['unreachable'] = {}

    if counts_fail != 0:
        for ip, fm in failed.items():
            key = ip.replace('.','_')
            msg = fm.get('msg')
            fail_msg['failed'][key] = 'Failed ' + msg

    if counts_unreachable != 0:
        for ip, fm in unreachable.items():
            msg = fm.get('msg')
            key = ip.replace('.', '_')
            fail_msg['unreachable'][key] = 'Unreachable ' + msg

    return fail_msg


if __name__ == '__main__':
    app.run(port=5002, debug=True)
